//
// Created by Tony on 2024/6/30.
//

#ifndef RT_CODE_ACCESS_FLAG_H
#define RT_CODE_ACCESS_FLAG_H

#include <cstdint>
#include <string>

namespace RtCode {

class AccessFlag {
public:
    static constexpr uint16_t PUBLIC = 0x0001;
    static constexpr uint16_t PRIVATE = PUBLIC << 1;
    static constexpr uint16_t PROTECTED = PRIVATE << 1;
    static constexpr uint16_t STATIC = PROTECTED << 1;
    static constexpr uint16_t FINAL = STATIC << 1;
    static constexpr uint16_t SYNCHRONIZED = FINAL << 1;
    static constexpr uint16_t VOLATILE = SYNCHRONIZED << 1;
    static constexpr uint16_t TRANSIENT = VOLATILE << 1;
    static constexpr uint16_t VARARGS = TRANSIENT << 1;
    static constexpr uint16_t NATIVE = VARARGS << 1;
    static constexpr uint16_t INTERFACE = NATIVE << 1;
    static constexpr uint16_t ABSTRACT = INTERFACE << 1;
    static constexpr uint16_t STRICT = ABSTRACT << 1;
    static constexpr uint16_t SYNTHETIC = STRICT << 1;
    static constexpr uint16_t ANNOTATION = SYNTHETIC << 1;
    static constexpr uint16_t ENUM = ANNOTATION << 1;

private:
    uint16_t mAccessFlag{};

public:
    AccessFlag() = default;
    explicit AccessFlag(uint16_t accessFlag) : mAccessFlag(accessFlag) {}

    void addFlag(uint16_t flag) { this->mAccessFlag |= flag; }
    bool isFlag(uint16_t flag) const { return (mAccessFlag & flag) != 0; }
    std::string toString() const;
};

} // namespace RtCode

#endif // RT_CODE_ACCESS_FLAG_H
